﻿<html><head></head>
<body><!--StartFragment-->

<p class="MsoNormal" style="margin-top:6.0pt;margin-right:0cm;margin-bottom:3.6pt;
margin-left:21.0pt;mso-para-margin-top:.5gd;mso-para-margin-right:0cm;
mso-para-margin-bottom:.3gd;mso-para-margin-left:21.0pt;text-indent:-21.0pt;
mso-outline-level:2;mso-list:l1 level1 lfo2"><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="font-size: 12pt; "><font class="Apple-style-span" face="Consolas"><br></font></span></b></p><p class="MsoNormal" style="margin-top:6.0pt;margin-right:0cm;margin-bottom:3.6pt;
margin-left:21.0pt;mso-para-margin-top:.5gd;mso-para-margin-right:0cm;
mso-para-margin-bottom:.3gd;mso-para-margin-left:21.0pt;text-indent:-21.0pt;
mso-outline-level:2;mso-list:l1 level1 lfo2"><font class="Apple-style-span" face="Consolas"><font class="Apple-style-span" size="5"><b>调用约定</b></font><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="font-size: 12pt; "><o:p></o:p></span></b></font></p><p class="MsoNormal" style="margin-top:6.0pt;margin-right:0cm;margin-bottom:3.6pt;
margin-left:21.0pt;mso-para-margin-top:.5gd;mso-para-margin-right:0cm;
mso-para-margin-bottom:.3gd;mso-para-margin-left:21.0pt;text-indent:-21.0pt;
mso-outline-level:2;mso-list:l1 level1 lfo2"><b style="mso-bidi-font-weight:normal"><span style="font-size: 12pt; "><font class="Apple-style-span" face="Consolas"><br></font></span></b></p>

<p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><span style="font-size: 11pt; line-height: 130%; "><font class="Apple-style-span" face="Consolas">在参数传递中，有两个很重要的问题必须得到明确说明：</font></span></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><span class="Apple-style-span" style="line-height: 19px; "><font class="Apple-style-span" face="Consolas">&nbsp; &nbsp; * 当参数个数多于一个时，按照什么<font class="Apple-style-span" color="#ff6600"><b>顺序</b></font>把参数压入堆栈</font></span></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><span class="Apple-style-span" style="line-height: 19px; "><font class="Apple-style-span" face="Consolas">&nbsp; &nbsp; * 函数调用后，由谁来把<font class="Apple-style-span" color="#ff6600"><b>堆栈恢复</b></font>原状</font></span></p><p class="MsoListParagraph" style="margin-left:21.0pt;line-height:120%;
mso-list:l0 level1 lfo1"><font class="Apple-style-span" face="Consolas"><br></font></p>

<p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><span style="font-size: 11pt; line-height: 130%; "><font class="Apple-style-span" face="Consolas">在高级语言中，通过函数调用约定来说明这两个问题。常见的调用约定有：</font></span></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><font class="Apple-style-span" face="Consolas"><span class="Apple-style-span" style="line-height: 19px; font-size: 15px;">&nbsp; &nbsp; *&nbsp;</span><span class="Apple-style-span" style="line-height: 19px; ">stdcall</span></font></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><span class="Apple-style-span" style="line-height: 19px; "><font class="Apple-style-span" face="Consolas">&nbsp; &nbsp; * cdecl</font></span></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><span class="Apple-style-span" style="line-height: 19px; "><font class="Apple-style-span" face="Consolas">&nbsp; &nbsp; * fastcall</font></span></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><span class="Apple-style-span" style="line-height: 19px; "><font class="Apple-style-span" face="Consolas">&nbsp; &nbsp; * thiscall</font></span></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
22.0pt;mso-char-indent-count:2.0;line-height:130%"><span class="Apple-style-span" style="line-height: 19px; "><font class="Apple-style-span" face="Consolas">&nbsp; &nbsp; * naked
call</font></span></p><p class="MsoListParagraph" style="margin-left:21.0pt;line-height:120%;
mso-list:l0 level1 lfo1"><font class="Apple-style-span" face="Consolas"><br></font></p><p class="MsoListParagraph" style="margin-left:21.0pt;line-height:120%;
mso-list:l0 level1 lfo1"><font class="Apple-style-span" face="Consolas"><br></font></p>

<p class="MsoNormal" align="left" style="margin-top:3.6pt;mso-para-margin-top:.3gd;
text-align:left;line-height:130%;mso-outline-level:3"><font class="Apple-style-span" face="Consolas"><font class="Apple-style-span" size="4"><b style="mso-bidi-font-weight:
normal"><span lang="EN-US" style="line-height: 130%; color: red; ">stdcall </span></b><b style="mso-bidi-font-weight:normal"><span style="line-height: 130%; ">调用约定</span></b><b style="mso-bidi-font-weight:
normal"><span lang="EN-US" style="line-height: 130%; ">(<span style="color:red">pascal</span></span></b><b style="mso-bidi-font-weight:
normal"><span style="line-height: 130%; ">调用约定</span></b></font><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="line-height: 130%; "><font class="Apple-style-span" size="4">)</font><font class="Apple-style-span" size="3"><o:p></o:p></font></span></b></font></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
21.0pt;line-height:130%"><font class="Apple-style-span" face="Consolas"><span style="font-size: 11pt; line-height: 130%; ">在</span><u><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">Microsoft
C++</span></u><u><span style="font-size: 11pt; line-height: 130%; ">系列</span></u><span style="font-size: 11pt; line-height: 130%; ">的</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">C/C++</span><span style="font-size: 11pt; line-height: 130%; ">编译器中，常常用</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">PASCAL</span><span style="font-size: 11pt; line-height: 130%; ">宏来声明这个调用约定，类似的宏还有</span><u><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">WINAPI</span></u><span style="font-size: 11pt; line-height: 130%; ">和</span><u><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">CALLBACK</span></u><span style="font-size: 11pt; line-height: 130%; ">。</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; "><o:p></o:p></span></font></p>

<p class="MsoNormal" style="text-indent:21.0pt;line-height:120%"><b style="mso-bidi-font-weight:normal"><i style="mso-bidi-font-style:normal"><span lang="EN-US" style="color: rgb(112, 48, 160); "><font class="Apple-style-span" face="Consolas">int __stdcall
function(int a,int b)<o:p></o:p></font></span></i></b></p><p class="MsoNormal" style="text-indent:21.0pt;line-height:120%"><b style="mso-bidi-font-weight:normal"><i style="mso-bidi-font-style:normal"><span lang="EN-US" style="color: rgb(112, 48, 160); "><font class="Apple-style-span" face="Consolas"><br></font></span></i></b></p>

<p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
21.0pt;line-height:130%"><font class="Apple-style-span" face="Consolas"><span lang="EN-US">stdcall</span>的调用约定意味着：<span lang="EN-US">1</span>）参数从右向左压入堆栈，<span lang="EN-US">2</span>）函数自身修改堆栈<span lang="EN-US"> 3)</span>函数名自动加前导的下划线，后面紧跟一个<span lang="EN-US">@</span>符号，其后紧跟着参数的尺寸<span lang="EN-US"><o:p></o:p></span></font></p>

<p class="MsoNormal" style="margin-top:1.5pt;text-indent:21.0pt;line-height:130%"><font class="Apple-style-span" face="Consolas">在编译时，这个函数的名字被翻译成<span lang="EN-US" style="color: red; ">_function@8</span><span lang="EN-US"><o:p></o:p></span></font></p>

<p class="MsoNormal" style="text-indent:21.0pt;line-height:120%"><font class="Apple-style-span" face="Consolas"><span lang="EN-US">[Ref 1] </span><span lang="EN-US"><a href="http://blog.csdn.net/fly2k5/article/details/544112">cdecl<span lang="EN-US"><span lang="EN-US">、</span></span>stdcall<span lang="EN-US"><span lang="EN-US">、</span></span>fastcall<span lang="EN-US"><span lang="EN-US">函数调用约定区别</span></span></a></span><span lang="EN-US"><o:p></o:p></span></font></p>

<p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;line-height:
130%;mso-outline-level:3"><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="font-size: 12pt; line-height: 130%; "><font class="Apple-style-span" face="Consolas"><br></font></span></b></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;line-height:
130%;mso-outline-level:3"><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="font-size: 12pt; line-height: 130%; "><font class="Apple-style-span" face="Consolas"><br></font></span></b></p><p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;line-height:
130%;mso-outline-level:3"><font class="Apple-style-span" face="Consolas"><font class="Apple-style-span" size="4"><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="line-height: 130%; ">cdecl </span></b><b style="mso-bidi-font-weight:normal"><span style="line-height: 130%; ">调用约定</span></b><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="line-height: 130%; ">(</span></b><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="line-height: 130%; ">C</span></b><b style="mso-bidi-font-weight:
normal"><span style="line-height: 130%; ">调用约定</span></b></font><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="line-height: 130%; "><font class="Apple-style-span" size="4">)</font><font class="Apple-style-span" size="3"><o:p></o:p></font></span></b></font></p>

<p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
21.0pt;line-height:130%"><font class="Apple-style-span" face="Consolas"><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">C</span><span style="font-size: 11pt; line-height: 130%; ">语言缺省的调用约定，它的定义语法是：</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; "><o:p></o:p></span></font></p>

<p class="MsoNormal" style="text-indent:21.0pt"><font class="Apple-style-span" face="Consolas"><span lang="EN-US"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp; </span><b style="mso-bidi-font-weight:normal"><i style="mso-bidi-font-style:normal"><span style="color:#7030A0">int function (int a ,int b)</span></i></b></span><b style="mso-bidi-font-weight:normal"><i style="mso-bidi-font-style:normal"><span style="color: rgb(112, 48, 160); ">　</span></i></b><span lang="EN-US">//</span>不加修饰就是<span lang="EN-US">C</span>调用约定<span lang="EN-US"><o:p></o:p></span></font></p>

<p class="MsoNormal" style="text-indent:21.0pt;line-height:120%"><font class="Apple-style-span" face="Consolas"><b style="mso-bidi-font-weight:normal"><i style="mso-bidi-font-style:normal"><span style="color: rgb(112, 48, 160); ">　　</span></i></b><b style="mso-bidi-font-weight:normal"><i style="mso-bidi-font-style:normal"><span lang="EN-US" style="color: rgb(112, 48, 160); ">int __cdecl function(int a,int b)<span style="mso-tab-count:
1">&nbsp; </span></span></i></b><span lang="EN-US" style="color: black; ">//</span><span style="color: black; ">明确指出</span><span lang="EN-US" style="color: black; ">C</span><span style="color: black; ">调用约定</span><b style="mso-bidi-font-weight:
normal"><i style="mso-bidi-font-style:normal"><span lang="EN-US" style="color: rgb(112, 48, 160); "><o:p></o:p></span></i></b></font></p>

<p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
21.0pt;line-height:130%"><font class="Apple-style-span" face="Consolas"><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">cdecl</span><span style="font-size: 11pt; line-height: 130%; ">调用约定的参数压栈顺序是和</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">stdcall</span><span style="font-size: 11pt; line-height: 130%; ">是一样的，参数首先由右向左压入堆栈。所不同的是，函数本身不清理堆栈，调用者负责清理堆栈。由于这种变化，</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">C</span><span style="font-size: 11pt; line-height: 130%; ">调用约定允许函数的参数的个数是不固定的，这也是</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">C</span><span style="font-size: 11pt; line-height: 130%; ">语言的一大特色。</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; "><o:p></o:p></span></font></p>

<p class="MsoNormal" style="margin-top:3.6pt;mso-para-margin-top:.3gd;text-indent:
21.0pt;line-height:130%"><font class="Apple-style-span" face="Consolas"><span lang="EN-US" style="font-size: 11pt; line-height: 130%; ">MSDN</span><span style="font-size: 11pt; line-height: 130%; ">中说，该修饰自动在函数名前加前导的下划线，因此函数名在符号表中被记录为</span><b style="mso-bidi-font-weight:normal"><span lang="EN-US" style="font-size: 11pt; line-height: 130%; color: red; ">_function</span></b><span style="font-size: 11pt; line-height: 130%; ">，但是我在编译时似乎没有看到这种变化。</span><span lang="EN-US" style="font-size: 11pt; line-height: 130%; "><o:p></o:p></span></font></p>

<p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US"><o:p><font class="Apple-style-span" face="Consolas"><br></font></o:p></span></p><p class="MsoNormal" style="text-indent:21.0pt"><span lang="EN-US" style="font-family:Consolas"><o:p><br></o:p></span></p>

<!--EndFragment-->

<script type="text/javascript" language="javascript" src="jquery.js"></script><script type="text/javascript" language="javascript" src="itemlink.js"></script></body></html>